package grpc

import (
	"context"
	"net"
	"os"
	"os/signal"
	"syscall"
	svr "wxpay/internal/handler/v1"
	v1 "wxpay/pkg/api/v1"
	"wxpay/pkg/mcontext"
	"wxpay/pkg/protocol/grpc/middleware"

	grpczap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap"
	"go.uber.org/zap"
	"google.golang.org/grpc"
	"google.golang.org/grpc/reflection"
)

func RunServer(ctx context.Context, port string, dsn string) error {
	logger := mcontext.Logger(ctx)

	// create a listener on TCP port
	lis, err := net.Listen("tcp", port)
	if err != nil {
		logger.Panic("failed to listen: %v", zap.Error(err))
	}
	service, err := svr.NewWxpayServer(dsn)
	if err != nil {
		logger.Panic("failed to start service: %v", zap.Error(err))
	}

	grpczap.ReplaceGrpcLoggerV2(logger)
	grpcServer := grpc.NewServer(grpc.ChainUnaryInterceptor(
		middleware.LogicIntInterceptor,
		middleware.ValidateInterceptor,
	))
	// attach the service to the server
	v1.RegisterWxpayServer(grpcServer, service)
	reflection.Register(grpcServer)

	quit := make(chan os.Signal)
	signal.Notify(quit, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)

	// 无限循环等待shutdown
	go func() {
		for range quit {
			logger.Info("Shutdown Server ...")
			svr.Close(ctx, service)
			grpcServer.GracefulStop()
			logger.Info("Server exiting")
		}
	}()

	logger.Info("starting rpc server...")
	return grpcServer.Serve(lis)
}
